package com.liyunc.demo.comp.json.mapper;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.liyunc.demo.comp.json.converter.CustomJsonDeserializer;
import com.liyunc.demo.comp.json.converter.CustomJsonSerializer;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDateTime;

/**
 * @author liyuncong
 * @version 1.0
 * @file CustomObjectMapper
 * @brief CustomObjectMapper
 * @details CustomObjectMapper
 * @date 2022-05-30
 *
 * Edit History
 * ----------------------------------------------------------------------------
 * DATE                        NAME               DESCRIPTION
 * 2022-05-30                      liyuncong          Created
 */
public class CustomObjectMapper extends ObjectMapper {

    private final PropertyNamingStrategy propertyNamingStrategy;

    public CustomObjectMapper(PropertyNamingStrategy propertyNamingStrategy) {
        this.propertyNamingStrategy = propertyNamingStrategy;
        this.setup();
    }

    protected final void setup() {
        JavaTimeModule timeModule = new JavaTimeModule();
        this.registerModule(timeModule);
        this._deserializationConfig = this.getDeserializationConfig()
            .without(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        this._serializationConfig = this.getSerializationConfig()
            .without(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
            .without(SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS)
            .without(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS)
            .with(SerializationFeature.WRITE_DATES_WITH_ZONE_ID);
        SimpleModule module = new SimpleModule("Precision-Keeping");
        module.addSerializer(long.class, ToStringSerializer.instance);
        module.addSerializer(double.class, ToStringSerializer.instance);
        module.addSerializer(Long.class, ToStringSerializer.instance);
        module.addSerializer(Double.class, ToStringSerializer.instance);
        module.addSerializer(BigDecimal.class, ToStringSerializer.instance);
        module.addSerializer(BigInteger.class, ToStringSerializer.instance);
        module.addSerializer(LocalDateTime.class, CustomJsonSerializer.dateJsonSerializer);
        module.addDeserializer(LocalDateTime.class, CustomJsonDeserializer.dateJsonDeserializer);
        this.registerModule(module);
        super.setPropertyNamingStrategy(this.propertyNamingStrategy);
    }
}
